package com.neusoft.databus.policy.model;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.validator.constraints.Length;

import com.google.common.collect.Lists;
import com.neusoft.bizcore.web.jpa.model.AbstractAuditModel;
import com.neusoft.databus.policy.enums.PolicyType;

import lombok.Getter;
import lombok.Setter;

/**
 * 策略
 *
 * @author naxiang
 */
@Getter
@Setter
@Entity
public class Policy extends AbstractAuditModel {

    private static final long serialVersionUID = -95825877739373267L;

    /**
     * 策略编码
     */
    @NotBlank(message = "策略编码不能为空")
    @Length(max = 255, message = "策略编码不能超过{max}位")
    @Column(length = 255, nullable = false, unique = true)
    private String code;

    /**
     * 策略名称
     */
    @NotBlank(message = "策略名称不能为空")
    @Length(max = 255, message = "策略名称不能超过{max}位")
    @Column(length = 255, nullable = false)
    private String name;

    /**
     * 禁用标识
     */
    private boolean disabled = false;

    /**
     * 拓展属性
     */
    @Length(max = 1023, message = "拓展属性不能超过{max}位")
    @Column(length = 1023)
    private String extendProperty;

    /**
     * 描述
     */
    @Length(max = 1023, message = "描述不能超过{max}位")
    @Column(length = 1023)
    private String description;

    /**
     * 策略执行频次 TODO: delete
     */
    //	@Length(max = 1023, message = "策略执行频次不能超过{max}位")
    //	@Column(length = 1023)
    //	private String frequency;

    /**
     * 判据。可扩展的误报保护判据 <br />
     * {"frequency": {"interval":"60000","times":"2"}}
     * 目前支持“频次判断法”，在interval间隔（毫秒）内，发生times次，才生成报警事件
     */
    @Length(max = 1023, message = "策略执行频次不能超过{max}位")
    @Column(length = 1023)
    private String criterion;

    /**
     * 策略类型
     */
    @Enumerated(EnumType.STRING)
    @NotNull(message = "策略类型不能为空")
    @Column(nullable = false)
    private PolicyType policyType;

    /**
     * 报警事件内容模板
     */
    @NotBlank(message = "报警事件内容模板不能为空")
    @Length(max = 1023, message = "报警事件内容模板不能超过{max}位")
    @Column(length = 1023, nullable = false)
    private String contentTemplate;

    /**
     * 关联指标表达式
     */
    @OneToMany(targetEntity = Expression.class, cascade = {CascadeType.ALL })
    @JoinTable(name = "ref_policy_expression", joinColumns = {
            @JoinColumn(name = "policy_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "expression_id", referencedColumnName = "id") })
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<Expression> expressions = Lists.newArrayList();

    /**
     * 策略-资源关联关系，关系由PolicyRefResource表维护
     */
    @OneToMany(targetEntity = PolicyRefResource.class, cascade = {
            CascadeType.ALL }, mappedBy = "policy", orphanRemoval = true)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<PolicyRefResource> policyRefResources = Lists.newArrayList();

    /**
     * 策略-资源关联关系，关系由PolicyRefResource表维护
     */
    @OneToMany(targetEntity = PolicyRefLinkage.class, cascade = {
            CascadeType.ALL }, mappedBy = "policy", orphanRemoval = true)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<PolicyRefLinkage> policyRefLinkages = Lists.newArrayList();

    @OneToMany(cascade = {CascadeType.REMOVE }, mappedBy = "policy")
    private List<Event> events = Lists.newArrayList();

}
